home *** CD-ROM | disk | FTP | other *** search
/ MacWorld UK 2000 March / MW_UK_2000_03.iso / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / metafontMode.tcl < prev    next >
Encoding:
Text File  |  1999-05-29  |  66.6 KB  |  2,192 lines  |  [TEXT/ALFA]

  1. #
  2. #
  3. #   This is metafontMode version 1.0.1
  4. #
  5. #
  6. #
  7. ##############################################################################################
  8. #                                                                                            #
  9. #   MetafontMode is a mode for the text editor Alpha: it is designed to make writing,        #
  10. #   processing and testing of Metafont source files much easier. Metafont is                 #
  11. #   the programming language written, as a companion to TeX, by Donald Knuth in              #
  12. #   order to create characters, fonts, font families (and many others things).               #
  13. #   Once Metafont mode is installed, the opening of a Metafont source file (i-e              #
  14. #   with extension .mf) invokes a new menu (called Metafont !) in the menu bar with          #
  15. #   the following features :                                                                 #
  16. #   —  easy insertion of all the basic Metafont commands (with electric stops).              #
  17. #   —  syntax colorizing.                                                                    #
  18. #   -  file marking.                                                                         #
  19. #   —  capacity to process a source file from within Alpha with various.                     #
  20. #      flags, printer modes, input base files.                                               #
  21. #   -  editing the log file.                                                                 #
  22. #   -  capacity to make the pk file; to make and to edit the property list for a font.       #
  23. #   -  capacity to process an entire folder of mf source files.                              #
  24. #                                                                                            #
  25. ##############################################################################################
  26. #
  27. # #    As of this release, only  CMacTeX Metafont and OzMetafont are supported (+ together with
  28. # #    gftopk and vftopl).
  29. #
  30. ########################################################################################
  31. #                                                                                      #
  32. #   ============================                                                       #
  33. #   Installation Instructions                                                          #
  34. #   ============================                                                       #
  35. #                                                                                      #
  36. #                                                                                      #
  37. #   Automatic installation :                                                           #
  38. #                                                                                      #
  39. #   Open the "OPEN TO INSTALL" file. Opening this file indicates to Alpha that a       #
  40. #   new package has to be installed : the procedure is automatic. Alpha knows          #
  41. #   where to store the different elements of you Metafont Mode package.                #
  42. #                                                                                      #
  43. #   Manual installation :                                                              #
  44. #                                                                                      #
  45. #   1-  put the "metafontMode.tcl" file in the "Modes" subfolder of the "Tcl"          #
  46. #   folder which is located at the same level as your Alpha application                #
  47. #                                                                                      #
  48. #   2-  put the "Metafont Help" file in the "Help" folder located at the same level    #
  49. #   as your Alpha application. Next time you launch Alpha, you will have a             #
  50. #   "Metafont Help" item in the Help menu to edit this file.                           #
  51. #                                                                                      #
  52. #   3-  launch Alpha. You need to rebuild the package indices and the tcl              #
  53. #   ones. 'Rebuild Package Indices' is in the Config->Packages menu, and "Rebuild Tcl  #
  54. #   Indices" is in the Tcl menu (press cmd-Y to open a tcl shell).                     #
  55. #                                                                                      #
  56. #   4-  quit Alpha and relaunch it : there you are.                                    #
  57. #                                                                                      #
  58. #                                                                                      #
  59. #           More explanations come in the Metafont Help file.                          #
  60. #                                                                                      #
  61. ########################################################################################
  62. ## 
  63.  ### 
  64.  ## Author :  Bernard Desgraupes  
  65.  ## e-mail:  berdesg@easynet.fr
  66.  ## www: <http://perso.easynet.fr/~berdesg/metafont.html>
  67.  ###
  68. ##
  69. ## 
  70.  # Copyright (c) 1999  Bernard Desgraupes
  71.  # 
  72.  # This    program    is free    software; you can redistribute it and/or modify
  73.  # it under    the    terms of the GNU General Public    License    as published by
  74.  # the Free    Software Foundation; either    version    2 of the License, or
  75.  # (at your    option)    any    later version.
  76.  # 
  77.  # This    program    is distributed in the hope that    it will    be useful,
  78.  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  79.  # MERCHANTABILITY or FITNESS FOR A    PARTICULAR PURPOSE.     See the
  80.  # GNU General Public License for more details.
  81.  # 
  82.  # You should have received    a copy of the GNU General Public License
  83.  # along with this program;    if not,    write to the Free Software
  84.  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,    USA.
  85.  ##
  86.  
  87.  
  88. alpha::mode Mf 1.0.1 mfMenu {*.mf *.fpl} mfMenu {
  89.     addMenu mfMenu "Metafont"
  90. } maintainer {
  91.     "Bernard Desgraupes" berdesg@easynet.fr <http://perso.easynet.fr/~berdesg/metafont.html> 
  92. } uninstall this-file help {file "Metafont Help"}
  93.  
  94.  
  95. #######   Preferences  #############
  96.  
  97. newPref f wordWrap {0} Mf
  98. newPref f autoMark {1} Mf
  99. # Flags for the six Metafont particular processing options
  100. # By default none of them is set
  101. newPref f gfcorners 0 Mf  shadowMf
  102. newPref f imagerules 0 Mf   shadowMf
  103. newPref f nodisplays 0 Mf   shadowMf
  104. newPref f notransforms 0 Mf   shadowMf
  105. newPref f screenstrokes 0 Mf   shadowMf
  106. newPref f screenchars 0 Mf   shadowMf
  107. # Name of the printer mode for Metafont : for instance cx at 300dpi, 
  108. # canonex at 600dpi etc.
  109. newPref v mfModeForPrinter canonex Mf
  110. newPref v prefixString {% } Mf
  111. newPref v funcExpr {[a-zA-Z_]*\(} Mf
  112. newPref v wordBreak {[_\w]+} Mf
  113. newPref v wordBreakPreface {[^_\w]} Mf
  114. # Here we allow the user to define his own 
  115. # denomination for the beginchar macro :
  116. newPref v userBeginchar beginchar Mf
  117. # Default colo(u)rs for the keywords
  118. newPref v commentColor red Mf
  119. newPref v funcColor cyan Mf
  120. newPref v keywordColor blue Mf
  121. newPref v stringColor green Mf
  122. # Metafont menu, when used for the first time, must determine
  123. # which Metafont application is installed. The lookForMetafont proc will do
  124. # that automatically, but this choice can be overriden afterwards
  125. # in the mode specific prefs.
  126. newPref v mfAppSig {} Mf 
  127. # Folder where Metafont sends its output to
  128. newPref folder outputFolder $HOME Mf
  129. # Where is the file modes.mf defining the parameters of 
  130. # all the possible Metafont modes :
  131. newPref file pathToModesMfFile {} Mf
  132. # Where is the file plain.mf defining the Metafont's basic macros :
  133. newPref file pathToPlainMfFile {} Mf
  134.  
  135.  
  136. ### 
  137.  #     Initialization of some variables
  138. ###
  139. set Mffilename [file tail [win::Current]]
  140. set chosenMode proof
  141. set mag 1
  142. set magstep 0
  143. set magflag 0
  144. set magstepflag 0
  145. set Mfbasefile ""
  146. set Mfbasefileflag 0
  147. set tfmfile ""
  148. set prefixtfm "("
  149. set prefixfpl "("
  150. set prefixgf "("
  151. set prefixlog "("
  152. set fromfolder "("
  153. set mfwd $HOME
  154. set mfset 0
  155. set gfall(CMT3) "("
  156. set gfall(OzMF) "("
  157.  
  158.  
  159.  
  160. proc mfMenu {} {}
  161.  
  162. hook::register activateHook rebuildOtherfiles Mf
  163.  
  164. #############  Select the Metafont application when using this mode for the first time #############
  165.  
  166. if {$MfmodeVars(mfAppSig)== ""} {
  167.     set mfsignlist [list "CMacTex mf" "OzMetafont" "DirectTeXPro mf"]
  168.     set sig [listpick -p "Select your Metafont application"  $mfsignlist]
  169.     switch $sig {
  170.         "CMacTex mf" {set mfAppSig "CMT3"}
  171.         "OzMetafont" {set mfAppSig "OzMF"}
  172.         "DirectTeXPro mf" {set mfAppSig "TeX+"}
  173.         }
  174.     removeArrDef MfmodeVars mfAppSig
  175.     set MfmodeVars(mfAppSig) $mfAppSig
  176.      addArrDef MfmodeVars mfAppSig $mfAppSig
  177. }
  178.  
  179. ##############################################
  180. #                                            #
  181. #   #########   Metafont Menu  ###########   #
  182. #                                            #
  183. ##############################################
  184.  
  185. menu::buildProc mfMenu menu::buildMf
  186. menu::buildProc otherFiles menu::buildotherFiles
  187.  
  188. proc menu::buildMf {} {
  189.     global mfMenu otherFiles Mffilename
  190.     set ma {
  191.     "/M<B<OswitchToMetafont"
  192.     "(-"
  193.     "/R<UrunTheBuffer"
  194.     "saveAndRun"
  195.     "<S<B/FrunAFile"
  196.     "<S<I<B/FrunAFolder"
  197.     "(-"
  198. {Menu -n "metafontMode" -p choosemodeProc {
  199.     "proof"
  200.     "smoke"
  201.     "localfont"
  202.     "userDefined"
  203.     }
  204. }
  205. {Menu -n "processingOptions" -p processingoptProc {
  206.     "mag..."
  207.     "magstep..."
  208.     "baseFile..."
  209.     "(-"
  210.     "gfcorners"
  211.     "imagerules"
  212.     "nodisplays"
  213.     "notransforms"
  214.     "screenchars"
  215.     "screenstrokes"
  216.     "(-"
  217.     "clearAllOptions"
  218.     }
  219. }
  220.     "(-"
  221. }
  222.     lappend ma [list Menu -n otherFiles {}]
  223.     append ma {
  224.       "(-"
  225.       "newFontTemplate"
  226.       "(-"
  227. {Menu -n "variables" -p variablesProc {    
  228.     " boolean"
  229.     " numeric"
  230.     " pair"
  231.     " path"
  232.     " pen"
  233.     " picture"
  234.     " string"
  235.     " transform"
  236.     }
  237. }
  238. {Menu -n "boolean" -p booleanProc {    
  239.     " charexists"
  240.     " cycle"
  241.     " false"
  242.     " known"
  243.     " true"
  244.     " unknown"
  245.     }
  246. }
  247. {Menu -n "functions" -p functionsProc {    
  248.     " angle"
  249.     " ceilling"
  250.     " floor"
  251.     " cosd"
  252.     " sind"
  253.     " mexp"
  254.     " mlog"
  255.     " sqrt"
  256.     "(-"
  257.     " eps"
  258.     " epsilon"
  259.     " infinity"
  260.     "(-"
  261.     " round"
  262.     " hround"
  263.     " vround"
  264.     "(-"
  265.     " solve"
  266.     " tolerance"
  267.     "(-"
  268.     " normaldeviate"
  269.     " randomseed"
  270.     " uniformdeviate"
  271.     " whatever"
  272.     }
  273. }
  274. {Menu -n "positioning" -p positioningProc {    
  275.     " clearxy"
  276.     " direction"
  277.     " directionpoint"
  278.     " directiontime"
  279.     " penoffset"
  280.     " point…of"
  281.     " precontrol…of"
  282.     " postcontrol…of"
  283.     " intersectionpoint"
  284.     " intersectiontimes"
  285.     "(-"
  286.     " good.bot"
  287.     " good.lft"
  288.     " good.rt"
  289.     " good.top"
  290.     " good.x"
  291.     " good.y"
  292.     "(-"
  293.     " xpart"
  294.     " xxpart"
  295.     " xypart"
  296.     " ypart"
  297.     " yxpart"
  298.     " yypart"
  299.     }
  300. }
  301. {Menu -n "paths" -p pathsProc {    
  302.     " flex"
  303.     " fullcircle"
  304.     " halfcircle"
  305.     " quartercircle"
  306.     " superellipse"
  307.     " unitsquare"
  308.     "(-"
  309.     " makepath"
  310.     " interpath"
  311.     " subpath"
  312.     " tensepath"
  313.     " counterclockwise"
  314.     " reverse"
  315.     "(-"
  316.     " turningnumber"
  317.     }
  318. }
  319. {Menu -n "pens" -p pensProc {    
  320.     " clear_pen_memory"
  321.     " clearpen"
  322.     " currentpen"
  323.     " makepen"
  324.     " nullpen"
  325.     " savepen"
  326.     "(-"
  327.     " pencircle"
  328.     " pencircle..."
  329.     " pensquare"
  330.     " pensquare..."
  331.     " penrazor"
  332.     " penspeck"
  333.     "(-"
  334.     " pen_bot"
  335.     " pen_lft"
  336.     " pen_rt"
  337.     " pen_top"
  338.     " pickup"
  339.     }
  340. }
  341. {Menu -n "pictures" -p picturesProc {    
  342.     " blankpicture"
  343.     " clearit"
  344.     " currentpicture"
  345.     " nullpicture"
  346.     "(-"
  347.     " totalweight"
  348.     " unitpixel"
  349.     }
  350. }
  351. {Menu -n "strings" -p stringsProc {    
  352.     " ditto"
  353.     " jobname"
  354.     " readstring"
  355.     " substring"
  356.     }
  357. }
  358. {Menu -n "transformations" -p transformationsProc {    
  359.     " currenttransform"
  360.     " identity"
  361.     " inverse"
  362.     " reflectedabout"
  363.     " rotated"
  364.     " rotatedaround"
  365.     " scaled"
  366.     " shifted"
  367.     " slanted"
  368.     " transformed"
  369.     " xscaled"
  370.     " yscaled"
  371.     " zscaled"
  372.     }
  373. }
  374. {Menu -n "definitions" -p definitionsProc {    
  375.     " def…enddef"
  376.     " suffix"
  377.     " expr"
  378.     " text"
  379.     " primarydef…enddef"
  380.     " secondarydef…enddef"
  381.     " tertiarydef…enddef"
  382.     " vardef…enddef"
  383.     " begingroup…endgroup"
  384.     }
  385. }
  386. {Menu -n "conditions" -p conditionsProc {    
  387.     " for…endfor"
  388.     " forever…endfor"
  389.     " forsuffixes…endfor"
  390.     " if…fi"
  391.     " if…elseif…else…fi"
  392.     " downto"
  393.     " upto"
  394.     " step…until"
  395.     " exitif"
  396.     " exitunless"
  397.     }
  398. }
  399. {Menu -n "drawing" -p drawingProc {    
  400.     " addto…also"
  401.     " addto…contour"
  402.     " addto…contour…withpen"
  403.     " addto…contour…withweight"
  404.     " addto…doublepath…withpen"
  405.     " addto…doublepath…withweight"
  406.     " cull…dropping"
  407.     " cull…dropping…withweight"
  408.     " cull…keeping"
  409.     " cull…keeping…withweight"
  410.     " cullit"
  411.     " cutdraw"
  412.     " cutoff"
  413.     " draw"
  414.     " drawdot"
  415.     " erase"
  416.     " fill"
  417.     " filldraw"
  418.     " penpos"
  419.     " penstroke"
  420.     " undraw"
  421.     " undrawdot"
  422.     " unfill"
  423.     " unfilldraw"
  424.     }
  425. }
  426. {Menu -n "characters" -p charactersProc {    
  427.     " beginchar…endchar"
  428.     " extra_beginchar"
  429.     " extra_endchar"
  430.     }
  431. }
  432. {Menu -n "units" -p unitsProc {    
  433.     " blacker"
  434.     " fillin"
  435.     " o_correction"
  436.     " fix_units"
  437.     " mode_setup"
  438.     " pixels_per_inchs"
  439.     }
  440. }
  441. {Menu -n "pixellisation" -p pixellisationProc {    
  442.     " define_pixels"
  443.     " define_blacker_pixels"
  444.     " define_good_x_pixels"
  445.     " define_good_y_pixels"
  446.     " define_corrected_pixels"
  447.     " define_horizontal_corrected_pixels"
  448.     " define_whole_pixels"
  449.     " define_whole_blacker_pixels"
  450.     " define_whole_vertical_pixels"
  451.     " define_whole_vertical_blacker_pixels"
  452.     }
  453. }
  454. {Menu -n "fontDefinitions" -p fontdefinitionsProc {    
  455.     " charlist"
  456.     " extensible"
  457.     " font_coding_scheme"
  458.     " font_extra_space"
  459.     " font_identifier"
  460.     " font_normal_shrink"
  461.     " font_normal_space"
  462.     " font_normal_stretch"
  463.     " font_quad"
  464.     " font_size"
  465.     " font_slant"
  466.     " font_x_height"
  467.     " fontdimen"
  468.     " headerbytes"
  469.     " ligtable"
  470.     " kern"
  471.     }
  472. }
  473. {Menu -n "displaying" -p displayingProc {    
  474.     " currentwindow"
  475.     " display…inwindow"
  476.     " openwindow…from…to…at"
  477.     " screen_cols"
  478.     " screen_rows"
  479.     " screenrule"
  480.     }
  481. }
  482. {Menu -n "output" -p outputProc {    
  483.     " openit"
  484.     " shipit"
  485.     " showit"
  486.     "(-"
  487.     " labels"
  488.     " labels…range…thru"
  489.     " penlabels"
  490.     " makelabel"
  491.     " makegrid..."
  492.     "(-"
  493.     " proofoffset"
  494.     " proofrule"
  495.     " proofrulethickness"
  496.     "(-"
  497.     " grayfont"
  498.     " labelfont"
  499.     " slantfont"
  500.     " titlefont"
  501.     }
  502. }
  503. {Menu -n "debugging" -p debuggingProc {    
  504.     " errhelp"
  505.     " errmessage"
  506.     " message"
  507.     " stop"
  508.     "(-"
  509.     " show"
  510.     " showdependencies"
  511.     " showstats"
  512.     " showtoken"
  513.     " showvariable"
  514.     "(-"
  515.     " loggingall"
  516.     " tracingall"
  517.     " tracingnone"
  518.     "(-"
  519.     " batchmode"
  520.     " errorstopmode"
  521.     " nonstopmode"
  522.     " scrollmode"
  523.     }
  524. }
  525. {Menu -n "misc" -p miscProc {    
  526.     " capsule_def"
  527.     " expandafter"
  528.     " gobble"
  529.     " gobbled"
  530.     " interact"
  531.     " numtok"
  532.     " scantokens"
  533.     " special"
  534.     " numspecial"
  535.     }
  536. }
  537. {Menu -n "internalVariables" -p varintProc {    
  538.     " autorounding"
  539.     " designsize"
  540.     " fontmaking"
  541.     " granularity"
  542.     " pausing"
  543.     " proofing"
  544.     " showstopping"
  545.     " smoothing"
  546.     "(-"
  547.     " charcode"
  548.     " chardp"
  549.     " chardx"
  550.     " chardy"
  551.     " charext"
  552.     " charht"
  553.     " charic"
  554.     " charwd"
  555.     "(-"
  556.     " hppp"
  557.     " vppp"
  558.     "(-"
  559.     " xoffset"
  560.     " yoffset"
  561.     "(-"
  562.     " day"
  563.     " month"
  564.     " year"
  565.     " time"
  566.     "(-"
  567.     " tracingcapsules"
  568.     " tracingchoices"
  569.     " tracingcommands"
  570.     " tracingedges"
  571.     " tracingequations"
  572.     " tracingmacros"
  573.     " tracingonline"
  574.     " tracingoutput"
  575.     " tracingpens"
  576.     " tracingrestores"
  577.     " tracingspecs"
  578.     " tracingstats"
  579.     " tracingtitles"
  580.     " turningcheck"
  581.     " warningcheck"
  582.     }
  583. }
  584. }
  585.     return [list build $ma mfmenuProc {otherFiles} $mfMenu]
  586. }
  587.  
  588. proc menu::buildotherFiles {} {
  589.     global Mffilename MfmodeVars outputFolder fromfolder
  590.     global prefixtfm prefixfpl prefixgf prefixlog gfall mfAppSig
  591.       set rootname [file rootname [file tail [win::Current]]]
  592.     set logname "${rootname}.log"
  593.     
  594. #     lappend ma "<S<I${fromfolder}convertAllGfToPk"
  595.     
  596.     set ma "<S${prefixgf}convertGfToPk"
  597.     lappend ma "<S<I$gfall($MfmodeVars(mfAppSig))convertAllGfToPk"
  598.     lappend ma     "<E<S${prefixtfm}convert $rootname.tfm to pl"
  599.     lappend ma     "<S<I${fromfolder}convertAllTfmToPl"
  600.     lappend ma     "tfmToPl..."
  601.     lappend ma     "(-"
  602.     lappend ma    "<S${prefixlog}open $rootname.log"
  603.     lappend ma    "<S<I${fromfolder}openAllLogFiles"
  604.     lappend ma "<E<S${prefixfpl}openPropertyList" 
  605.     lappend ma "<S<I${fromfolder}openAllPropertyLists" 
  606.     foreach i {"(-"  "(-" "openModes.mf" "openPlain.mf"} {
  607.     lappend ma $i
  608.         }
  609.     append ma {
  610.       "(-"
  611. {Menu -n "removeFiles…" -p removefilesProc {    
  612.     "allLogFiles" 
  613.     "allGfFiles" 
  614.     "allPkFiles" 
  615.     "allTfmFiles"
  616.     "allPlFiles"
  617.     "(-"
  618.     "allOfThem"
  619.     }
  620. }
  621. }
  622.     return [list build $ma otherfilesProc]
  623. }
  624.  
  625. menu::buildSome mfMenu 
  626.  
  627. markMenuItem metafontMode proof 1
  628.  
  629. ################################################################
  630. #                     Menus and submenus procs                 #
  631. ################################################################
  632.  
  633.  
  634. ############  Top menu procs ##############
  635.  
  636. proc mfmenuProc {menu item} {
  637.     global fullMffilename tailMffilename MfmodeVars cmdline
  638.     switch $item {
  639.         "switchToMetafont" {app::launchFore CMT3}
  640.         "runTheBuffer" {
  641.             set fullMffilename [win::Current]
  642.             set tailMffilename [file tail $fullMffilename]
  643.             checkdirty
  644.             runbufferProc}
  645.         "saveAndRun" {
  646.             save
  647.             set fullMffilename [win::Current]
  648.             set tailMffilename [file tail $fullMffilename]
  649.             runbufferProc
  650.             }
  651.         "runAFile" {
  652.             catch {getfile "Find a \".mf\" file to process"}  fullMffilename
  653.             edit $fullMffilename
  654.             if [file exists $fullMffilename] {
  655.                 set tailMffilename [file tail $fullMffilename]
  656.                 runbufferProc
  657.                 }
  658.             }
  659.         "runAFolder" {runafolderProc}
  660.         "newFontTemplate" {newtemplateProc}
  661.     }
  662. }
  663.  
  664. proc findmoderes {} {
  665.     global MfmodeVars mfAppSig chosenMode
  666.     if {$chosenMode == "proof"} {
  667.     return [list "proof" "2602"]
  668.     }
  669.     if {$chosenMode == "smoke"} {
  670.     return [list "smoke" "2602"]
  671.     }
  672.     set rootname [file rootname [file tail [win::Current]]]
  673.     if {[file exists $MfmodeVars(pathToModesMfFile) ]} {
  674.         message "reading $MfmodeVars(pathToModesMfFile)"
  675.         catch {open "$MfmodeVars(pathToModesMfFile)"} fileId
  676.         catch {read $fileId} textlog
  677.         # First we find the value of localfont
  678.         if {$chosenMode == "localfont"} {
  679.             regexp {localfont([^\;]*)\;} $textlog blabla localMfmode
  680.             set localMfmode [string trim $localMfmode " :="]
  681.         } elseif {$chosenMode == "smoke"} {
  682.             set localMfmode $chosenMode
  683.         } else {
  684.             set localMfmode $MfmodeVars(mfModeForPrinter)            
  685.         }
  686.         # Then we find the resolution in dpi
  687.         set start [string first "mode_def $localMfmode" $textlog]
  688.         if {$start == -1} {
  689.             alertnote "Unknown mode $localMfmode."
  690.             return
  691.         }
  692.         set textlog [string range $textlog $start end]
  693.         regexp {pixels_per_inch[^0-9)]*([0-9]*)} $textlog blabla resdpi
  694.         return [list $localMfmode $resdpi]
  695.     } else {
  696.         alertnote "Can't find file modes.mf : set the path in the Current Mode Prefs."
  697.         return [list "proof" "2602"]
  698.     }
  699. }
  700.  
  701. proc otherfilesProc {submenu item} {
  702.     global rootname MfmodeVars outputFolder mfAppSig gffile mfwd prefixfpl
  703.     switch -regexp $item {
  704.         "convertGfToPk"  {
  705.             findrootnameProc
  706.             findgfFile
  707.             dopkProc
  708.         }
  709.         "convert.*\.tfm"  {
  710. #             if [app::isRunning CMTk] {sendQuitEvent 'CMTk'}
  711.             findoutputfolder
  712.             findrootnameProc
  713.             doplProc
  714.             set prefixfpl ""
  715.             menu::buildSome otherFiles
  716.             editplProc
  717.         }
  718.         "tfmToPl..." {
  719.             global tfmfile rootname
  720.             catch {getfile "Select a tfm file"}  tfmfile
  721.             if {$tfmfile == ""} {
  722.                 return} else {
  723.                     set rootname [file rootname [file tail $tfmfile]]
  724.                     doplProc
  725.                     editplProc
  726.                     set tfmfile ""
  727.                     }
  728.                 }
  729.         "open.*\.log$" {
  730.                 findrootnameProc
  731.                 switch $MfmodeVars(mfAppSig) {
  732.                     "CMT3" {     
  733.                         findoutputfolder
  734.                         if {![file exists $MfmodeVars(outputFolder):${rootname}.log]} {
  735.                             alertnote "Can't find file ${rootname}.log."
  736.                             return} else {
  737.                                 edit -r "$MfmodeVars(outputFolder):${rootname}.log"
  738.                             }
  739.                         }
  740.                         "OzMF" {
  741.                             set logdirname [file dirname [win::Current]]
  742.                             if {![file exists $logdirname:${rootname}.log]} {
  743.                                 alertnote "Can't find file ${rootname}.log. Check that the \"delete_log\" flag in OzMetafont configs is set to false."
  744.                                 return} else {
  745.                                     edit -r "$logdirname:${rootname}.log"
  746.                                 }
  747.                             }
  748.                         "TeX+"  {
  749.                             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  750.                         }
  751.                     }
  752.                 }
  753.         "openPropertyList" {
  754.                     findrootnameProc
  755.                     editplProc
  756.                 }
  757.         "convertAllGfToPk" {convertallProc gftopk}
  758.         "convertAllTfmToPl" {convertallProc vftopl}
  759.         "openAllLogFiles" {allAuxfilesProc log}
  760.         "openAllPropertyLists" {
  761.                     switch $MfmodeVars(mfAppSig) {
  762.                         "CMT3" {allAuxfilesProc fpl}
  763.                         "OzMF" {allAuxfilesProc pl}
  764.                         "TeX+" {allAuxfilesProc pl}
  765.                     }
  766.                 }
  767.         "openModes.mf" {openmodesmfProc}
  768.         "openPlain.mf" {openplainmfProc}
  769.     }
  770. }
  771.         
  772. # Here we define a proc to dimm/undimm the items of the OtherFiles submenu
  773. # depending on the existence of auxiliary files
  774. proc rebuildOtherfiles {name} {
  775.     global mfMenu otherFiles Mffilename
  776.     global MfmodeVars outputFolder mfAppSig
  777.     global prefixgf prefixlog prefixtfm prefixfpl
  778.     set Mffilename [file tail [win::Current]]
  779.     switch $MfmodeVars(mfAppSig) {
  780.         "CMT3" {     
  781.             set Mfdirname $MfmodeVars(outputFolder)
  782.         }
  783.         "OzMF" {
  784.             set Mfdirname [file dirname [win::Current]]
  785.             }
  786.         "TeX+"  {
  787.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  788.             set Mfdirname $MfmodeVars(outputFolder)
  789.         }
  790.     }
  791.     if {![regexp ".mf" $Mffilename] && ![regexp ".fpl" $Mffilename]} {
  792.         set prefixgf "("
  793.         set prefixlog "("
  794.         set prefixtfm "("
  795.         set prefixfpl "("
  796.         } else {
  797.             set rootname [file rootname $Mffilename]
  798.             set logname "${rootname}.log"
  799.             if [file exists $Mfdirname:${logname}] {
  800.                 set prefixgf ""
  801.                 set prefixlog ""
  802.             } else {
  803.                 set    prefixgf "("
  804.                 set    prefixlog "("}
  805.             if [file exists $Mfdirname:${rootname}.tfm] {
  806.                 set prefixtfm ""
  807.             } else {
  808.                 set    prefixtfm "("}
  809.             if [file exists $Mfdirname:${rootname}.fpl] {
  810.                 set prefixfpl ""
  811.                 } elseif [file exists $Mfdirname:${rootname}.pl] {
  812.                     set prefixfpl ""
  813.                 } else {
  814.                 set    prefixfpl "("}
  815.         }
  816.     menu::buildSome otherFiles
  817. }
  818.  
  819. # Here are the procs to process the source files
  820. proc runbufferProc {} {
  821.     global fullMffilename tailMffilename cmdline addcmdline MfmodeVars mfAppSig 
  822.     global prefixtfm prefixfpl prefixgf prefixlog chosenMode resol
  823.     if {[string length $MfmodeVars(mfAppSig)]} {
  824.         app::launchFore "$MfmodeVars(mfAppSig)"
  825.         switch $MfmodeVars(mfAppSig) {
  826.             "CMT3" {     
  827.                 buildCMTcmdLine
  828.                 doMfscript
  829.             }
  830.             "OzMF" {
  831.                 if {$chosenMode == "proof"} {
  832.                     doMfscript
  833.                     updateprefixes
  834.                 } else {
  835.                     set resol "[findmoderes]"
  836.                     buildOZmakeLine
  837.                     createmakefile
  838.                     runmakefile
  839.                     updateprefixes
  840.                 }
  841.             }
  842.             "TeX+"  {
  843.                 app::launchFore "ALFA"
  844.                 alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  845.                 return
  846.             }
  847.         }
  848.         menu::buildSome otherFiles
  849.     } else {
  850.         alertnote "No Mf app. selected. Select it in the Current mode preferences."
  851.     }
  852. }
  853.  
  854. proc runafolderProc {} {
  855.     global fullMffilename tailMffilename cmdline folderpath fromfolder
  856.     global MfmodeVars outputFolder mfAppSig chosenMode resol filesindir ext
  857.     catch {get_directory -p "Select a folder."} folderpath
  858.     if {$folderpath == ""} { return }
  859.     set ext ".mf"
  860.     set filesindir [glob -nocomplain "$folderpath:*$ext"]
  861.     set longueur [llength $filesindir]
  862.     if {$longueur == 0} {
  863.         alertnote "No \"$ext\" file in this folder."
  864.         return } 
  865.     if {[string length $MfmodeVars(mfAppSig)]} {
  866.         app::launchFore "$MfmodeVars(mfAppSig)"
  867.         switch $MfmodeVars(mfAppSig) {
  868.             "CMT3" {domaketexpk}
  869.             "OzMF" {domaketexpk}
  870.             "TeX+"  {
  871.                 app::launchFore "ALFA"
  872.                 alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  873.                 return
  874.             }
  875.         }
  876.         set fromfolder ""
  877.         menu::buildSome otherFiles
  878.     } else {
  879.         alertnote "No Mf app. selected. Select it in the Current mode preferences."
  880.     }                    
  881. }    
  882.     
  883.  
  884. proc domaketexpk {} {
  885.     global fullMffilename tailMffilename cmdline folderpath fromfolder
  886.     global chosenMode resol filesindir
  887.     global MfmodeVars outputFolder mfAppSig ext
  888.     if {[file exists "$folderpath:tmpall.make" ]} {
  889.         removeFile "$folderpath:tmpall.make"
  890.     }
  891.     switch [buttonAlert "OK to process all \"$ext\" files from $folderpath ?  This folder must be on a path searched by Metafont." "yes" "cancel" ] {
  892.         "yes" {
  893.             set fileId [open "$folderpath:tmpall.make" a+] 
  894.             set resol  "[findmoderes]"
  895.             foreach file $filesindir {
  896.                 set fullMffilename $file
  897.                 set tailMffilename [file tail $file]
  898.                 buildOZmakeLine
  899.                 puts $fileId $cmdline
  900.             }
  901.             close $fileId
  902.             runmakeallfile
  903.         }
  904.         "cancel" {
  905.             switchTo 'ALFA'
  906.             return 
  907.         }
  908.     }
  909. }
  910.  
  911. proc checkdirty {} {
  912.         if {[winDirty]} {
  913.         case [askyesno -c "Dirty window '[lindex [winNames] 0]'. Do you want to save it ?"] in {
  914.             "yes" {save}
  915.             "no" {}
  916.             "cancel" {return}
  917.             }
  918.         }
  919. }
  920.  
  921. ####################  Scripts and auxiliary programms  #########################
  922.  
  923. proc buildCMTcmdLine {} {
  924.     global cmdline fullMffilename tailMffilename MfmodeVars chosenMode mfModeForPrinter outputFolder
  925.     global proof smoke localfont userDefined script
  926.     global gfcorners imagerules nodisplays
  927.     global notransforms screenchars screenstrokes
  928.     global mag magstep magflag magstepflag Mfbasefile Mfbasefileflag
  929.     global prefixtfm prefixfpl prefixgf prefixlog
  930.     set cmdline "mf "
  931. #    choosing the mode
  932.     if {$chosenMode != "proof"} {
  933.         if {$chosenMode == "smoke" || $chosenMode == "localfont"} {
  934.             append cmdline "\\mode=$chosenMode; "
  935.             } else {
  936.             append cmdline "\\mode=$MfmodeVars(mfModeForPrinter);"}
  937.         } else {append cmdline "\\ "}
  938. #   Do we magnify ?
  939.        if {$magflag == 1} {append cmdline "mag=$mag; "
  940.         } elseif {$magstepflag == 1} {
  941.             append cmdline "mag=magstep\($magstep\); "
  942.             }
  943. #    Add the (optional!) options if the corresponding flag is set
  944.     if $screenchars {append cmdline "screenchars; "}
  945.     if $screenstrokes {
  946.             if {$chosenMode != "proof"} {
  947.             alertnote "The \"screenstrokes\" option is for proof mode only. I'll ignore it."
  948.             mfToggle screenstrokes
  949.             shadowMf screenstrokes
  950.         } else {
  951.         append cmdline "screenstrokes; "}
  952.     }
  953.     if $imagerules {
  954.         append cmdline "imagerules; "}
  955.     if $gfcorners {
  956.         append cmdline "gfcorners; "}
  957.     if $nodisplays {
  958.         if {$chosenMode != "proof"} {
  959.             alertnote "The \"nodisplays\" option is for proof mode only. I'll ignore it."
  960.         } elseif {$screenchars || $screenstrokes} {beep 
  961.             alertnote "Contradictory options : you can't use \"nodisplays\" with \"screenchars\" or \"screenstrokes\". I'll ignore it."
  962.             mfToggle nodisplays
  963.             shadowMf nodisplays
  964.         } else {
  965.         append cmdline "nodisplays; "}
  966.     }
  967.     if $notransforms {
  968.         append cmdline "notransforms; "}
  969. #    Input a base file if any
  970.     if {$Mfbasefileflag == 1} {
  971.         append cmdline "input $Mfbasefile;"
  972.         }
  973. #   Now the file to process. Since version 2.2.1 of CMaCTeX Metafont there is a new syntax 
  974. #     for the Apple event : the destination folder is included in the script line
  975. #     and introduced by -@
  976.     if {[lindex [getMfVersion] 1] <= 2.2} {
  977.             append cmdline "input $tailMffilename;"
  978.         } else {
  979.             append cmdline "input $tailMffilename -@ [set MfmodeVars(outputFolder)]:"
  980.         }
  981.     set cmdline [curlyq $cmdline]
  982. #     Finally we update prefixes to rebuild accordingly the Other Files submenu
  983.     updateprefixes
  984. }
  985.  
  986. proc buildOZmakeLine {} {
  987.     global cmdline fullMffilename tailMffilename MfmodeVars chosenMode
  988.     global proof smoke localfont userDefined script resol mfModeForPrinter
  989.     global gfcorners imagerules nodisplays
  990.     global notransforms screenchars screenstrokes
  991.     global mag magstep magflag magstepflag Mfbasefile Mfbasefileflag
  992.     global prefixtfm prefixfpl prefixgf prefixlog
  993. # OzMetafont cannot receive a complete command line through an Apple Event. 
  994. # The workaround is to create a ".make" file which OzMetafont will process 
  995. # with its built-in MakeTeXPK.
  996. #         Side effect : the "pk" files will be done in the same time,
  997. #         thus no need to invoke gftopk after that.
  998.     set cmdline "MakeTeXPK [file rootname $tailMffilename] "
  999. # What is the resolution corresponding to the printer mode ? We look for it in the
  1000. # modes.mf file.
  1001.     append cmdline "[lindex $resol 1] [lindex $resol 1] "
  1002. #   Do we magnify ?
  1003.     if {$magflag == 1} {append cmdline "$mag "
  1004.     } elseif {$magstepflag == 1} {
  1005.     append cmdline "magstep\($magstep\) "
  1006.     } else {
  1007.     append cmdline "1 "}
  1008. #   Choose the mode
  1009.     if {$chosenMode == "localfont"} {
  1010.         append cmdline     "[lindex $resol 0]"    
  1011.     } elseif {$chosenMode == "proof" || $chosenMode == "smoke"} {
  1012.         append cmdline "$chosenMode"
  1013.     } else {
  1014.         append cmdline $MfmodeVars(mfModeForPrinter)
  1015.     }
  1016. #    Add the (optional!) options if the corresponding flag is set
  1017.     if $screenchars {append cmdline ";screenchars"}
  1018.     if $screenstrokes {
  1019.         if {$chosenMode != "proof"} {
  1020.             alertnote "The \"screenstrokes\" option is for proof mode only. I'll ignore it."
  1021.             mfToggle screenstrokes
  1022.             shadowMf screenstrokes
  1023.         } else {
  1024.             append cmdline ";screenstrokes"}
  1025.         }
  1026.         if $imagerules {
  1027.             append cmdline ";imagerules"}
  1028.         if $gfcorners {
  1029.             append cmdline ";gfcorners"}
  1030.         if $nodisplays {
  1031.             if {$chosenMode != "proof"} {
  1032.                 alertnote "The \"nodisplays\" option is for proof mode only. I'll ignore it."
  1033.             } elseif {$screenchars || $screenstrokes} {beep 
  1034.                 alertnote "Contradictory options : you can't use \"nodisplays\" with \"screenchars\" or \"screenstrokes\". I'll ignore it."
  1035.                 mfToggle nodisplays
  1036.                 shadowMf nodisplays
  1037.             } else {
  1038.                 append cmdline ";nodisplays"}
  1039.             }
  1040.         if $notransforms {
  1041.             append cmdline ";notransforms"}
  1042. #    Input a base file if any
  1043.         if {$Mfbasefileflag == 1} {
  1044.             append cmdline ";input $Mfbasefile"
  1045.         }
  1046. #     Finally we update prefixes to rebuild the "Other Files" submenu
  1047.     updateprefixes
  1048. }
  1049.                 
  1050. proc doMfscript {} {
  1051.     global cmdline addcmdline fullMffilename script rootname
  1052.     global MfmodeVars mfAppSig
  1053.     switch $MfmodeVars(mfAppSig) {
  1054.         "CMT3" {     
  1055.              eval "AEBuild -t 6000 'CMT3'" CMTX exec {----} [list $cmdline] 
  1056.             }
  1057.         "OzMF" {
  1058.             app::launchFore "OzMF"
  1059.             dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f $fullMffilename
  1060.             }
  1061.         "TeX+"  {
  1062.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1063.         }
  1064.     }
  1065. }
  1066.  
  1067. proc createmakefile {} {
  1068.     global cmdline fullMffilename
  1069.     set fileId [open "[file dirname $fullMffilename]:tmp.make" w+] 
  1070.     puts $fileId $cmdline
  1071.     close $fileId
  1072. }
  1073.     
  1074. proc runmakefile {} {
  1075.     global fullMffilename
  1076.     app::launchFore "OzMF"
  1077.     dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f "[file dirname $fullMffilename]:tmp.make"
  1078. }
  1079.         
  1080. proc runmakeallfile {} {
  1081.     global folderpath MfmodeVars mfAppSig
  1082.     switch $MfmodeVars(mfAppSig) {
  1083.         "CMT3" {
  1084.             app::launchFore "CMT9"
  1085.             dosc -c 'CMT9' -k 'aevt' -e 'odoc' -t 600 -r -f "$folderpath:tmpall.make"
  1086.         }
  1087.         "OzMF" {
  1088.             app::launchFore "OzMF"
  1089.             dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f "$folderpath:tmpall.make"                            
  1090.         }
  1091.     }
  1092. }
  1093.     
  1094. proc updateprefixes {} {
  1095.     global prefixtfm prefixfpl prefixgf prefixlog chosenMode
  1096.     if {$chosenMode == "proof"  || $chosenMode == "smoke"} {
  1097.         set prefixtfm "("
  1098.             } else {
  1099.         set prefixtfm ""}
  1100.     set prefixfpl "("
  1101.     set prefixgf ""
  1102.     set prefixlog ""
  1103. }
  1104.  
  1105.  
  1106. # This proc calls gftopk up
  1107. proc dopkProc {} {
  1108.     global gffile MfmodeVars outputFolder mfAppSig mfset 
  1109.     global mfwd folderpath
  1110.     switch $MfmodeVars(mfAppSig) {
  1111.         "CMT3" {
  1112.             if {![file exists $mfwd:$gffile]} {
  1113.                 alertnote "Can't find file $gffile."
  1114.                 return}
  1115.             set pkcmdline "gftopk $mfwd:$gffile"
  1116.             app::launchFore "CMTe"
  1117.             set pkcmdline [curlyq $pkcmdline]
  1118.             eval "AEBuild 'CMTe'" CMTX exec {----} [list $pkcmdline]
  1119.             }
  1120.         "OzMF" {
  1121.             if {![file exists $mfwd:$gffile]} {
  1122.                 alertnote "Can't find file $gffile. Check that the \"delete_gf\" flag in OzMetafont configs is set to false."
  1123.                 return}
  1124.             app::launchFore "OzMF"
  1125.             dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 6000 -r -f "$mfwd:$gffile"
  1126.             }
  1127.         "TeX+"  {
  1128.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1129.         }
  1130.     }
  1131. }
  1132.  
  1133. # This proc calls vftopl up
  1134. proc doplProc {} {
  1135.     global rootname MfmodeVars outputFolder mfAppSig tfmfile mfset 
  1136.     global mfwd folderpath
  1137.     switch $MfmodeVars(mfAppSig) {
  1138.         "CMT3" {     
  1139.             if $mfset {
  1140.             set mfwd $folderpath
  1141.             } else {set mfwd $MfmodeVars(outputFolder)}
  1142.             if {$tfmfile != ""} {
  1143.                 set plcmdline "tftopl $tfmfile $mfwd:${rootname}.fpl"
  1144.             } else {
  1145.                 if {![file exists $mfwd:${rootname}.tfm]} {
  1146.                     alertnote "Can't find file ${rootname}.tfm. Check your mode (no tfm in proof or smoke modes)."
  1147.                     return}
  1148.                 set plcmdline "tftopl $mfwd:${rootname}.tfm $mfwd:${rootname}.fpl"
  1149.             }
  1150.             app::launchFore "CMTk"
  1151.             set plcmdline [curlyq $plcmdline]
  1152.             eval "AEBuild -r 'CMTk'" CMTX exec {----} [list $plcmdline]
  1153. #             app::launchFore "ALFA"
  1154.         }
  1155.         "OzMF" {
  1156.             if $mfset {
  1157.             set mfwd $folderpath
  1158.             } else {set mfwd [file dirname [win::Current]]}
  1159.             if {![file exists $mfwd:${rootname}.tfm]} {
  1160.                 alertnote "Can't find file ${rootname}.tfm. Check that the \"delete_tfm\" flag in OzMetafont configs is set to false."
  1161.                 return}
  1162.             app::launchBack "OzMF"
  1163.             if {$tfmfile != ""} {
  1164.             dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f $tfmfile                
  1165.                 } else {
  1166.             dosc -c 'OzMF' -k 'aevt' -e 'odoc' -t 600 -r -f "$mfwd:${rootname}.tfm"
  1167.             app::launchFore "ALFA"
  1168.             }
  1169.         }
  1170.         "TeX+"  {
  1171.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1172.         }
  1173.     }
  1174. }
  1175.  
  1176. proc editplProc {} {
  1177.         global rootname MfmodeVars outputFolder mfAppSig 
  1178.         global mfwd tfmfile
  1179.     switch $MfmodeVars(mfAppSig) {
  1180.         "CMT3" {     
  1181.             while {![file exists "$mfwd:${rootname}.fpl"]} {}
  1182.             edit -r "$mfwd:${rootname}.fpl"
  1183.             if [app::isRunning CMTk] {sendQuitEvent 'CMTk'}
  1184.         }
  1185.         "OzMF" {
  1186.             if {$tfmfile != ""} {
  1187.                 if {[file exists "[file dirname $tfmfile]:[file rootname [file tail $tfmfile]].pl"]} {
  1188.                     edit -r "[file dirname $tfmfile]:[file rootname [file tail $tfmfile]].pl"
  1189.                 } else {alertnote "Can't find [file rootname [file tail $tfmfile]].pl"}
  1190.             } else {
  1191.                 if {[file exists "$mfwd:${rootname}.pl"]} {
  1192.                     edit -r "$mfwd:${rootname}.pl"
  1193.                 } else {alertnote "Can't find ${rootname}.pl in $mfwd."}
  1194.             }
  1195.         }
  1196.         "TeX+"  {
  1197.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1198.         }
  1199.     }
  1200.             set prefixfpl ""
  1201.             menu::buildSome otherFiles
  1202. }
  1203.  
  1204.  
  1205. #########   Choosing Metafont printer mode for processing   ##################
  1206.  
  1207. proc choosemodeProc {menu item} {
  1208.         global MfmodeVars mfModeForPrinter chosenMode
  1209.         global proof smoke localfont userDefined
  1210.     switch $item {
  1211.         "proof" {set chosenMode proof
  1212.             choosemodeMark proof
  1213.             dimmOtherfiles
  1214.             message "mode proof - no tfm produced"
  1215.             }
  1216.         "smoke" {set chosenMode smoke
  1217.             choosemodeMark smoke
  1218.             dimmOtherfiles
  1219.             message "mode smoke - no tfm produced"
  1220.             }
  1221.         "localfont" {set chosenMode localfont
  1222.             choosemodeMark localfont
  1223.             undimmOtherfiles
  1224.             }
  1225.         "userDefined" {set chosenMode $MfmodeVars(mfModeForPrinter)
  1226.             choosemodeMark userDefined
  1227.             undimmOtherfiles
  1228.             alertnote "Current user defined mode is $MfmodeVars(mfModeForPrinter). You can change this in the Current Mode Prefs."
  1229.         }
  1230.     }
  1231. }
  1232.  
  1233. proc choosemodeMark {var} {
  1234.             clearAllModes
  1235.             markMenuItem metafontMode $var 1
  1236. }
  1237.  
  1238. proc clearAllModes {} {
  1239.     global proof smoke localfont userDefined
  1240.         foreach i {"proof" "smoke" "localfont" "userDefined"} {
  1241.             markMenuItem metafontMode $i 0
  1242.             } 
  1243. }
  1244.  
  1245.  
  1246.  
  1247. #####################   Metafont processing Options   ######################################
  1248.  
  1249. proc processingoptProc {menu item} {
  1250.     global mag magstep magflag magstepflag Mfbasefileflag
  1251.     global MfmodeVars Mfbasefile
  1252.     switch $item {    
  1253.     "mag..." {
  1254.             catch {prompt "Choose a magnification" $mag} res
  1255.             if {$res == "cancel"} {return}
  1256.             if {$res == 1} {
  1257.                     set magflag 0
  1258.                     set mag $res
  1259.                     markMenuItem processingOptions "mag..." $magflag
  1260.                 } else {
  1261.                     set magstep 0
  1262.                     set magstepflag 0
  1263.                     set magflag 1
  1264.                     set mag $res
  1265.                     markMenuItem processingOptions "mag..." $magflag
  1266.                     markMenuItem processingOptions "magstep..." $magstepflag
  1267.                     }
  1268.         }
  1269.     "magstep..." {
  1270.             catch {prompt "Choose a magstep coefficient " $magstep} res
  1271.             if {$res == "cancel"} {return}
  1272.             if {$res == 0} {
  1273.                     set magstepflag 0
  1274.                     set magstep $res
  1275.                     markMenuItem processingOptions "magstep..." $magstepflag
  1276.                 } else {
  1277.                     set mag 1
  1278.                     set magflag 0
  1279.                     set magstepflag 1
  1280.                     set magstep $res
  1281.                     markMenuItem processingOptions "mag..." $magflag
  1282.                     markMenuItem processingOptions "magstep..." $magstepflag
  1283.                     }
  1284.         }
  1285.     "baseFile..." {
  1286.         catch {getfile "Select a base file"} Mfbasefilepath
  1287.         set Mfbasefile [file tail $Mfbasefilepath] 
  1288.         set Mfbasefileflag 1
  1289.         markMenuItem processingOptions "baseFile..." $Mfbasefileflag
  1290.     }
  1291.     "gfcorners" {mfToggle gfcorners}
  1292.     "imagerules" {mfToggle imagerules}
  1293.     "nodisplays" {mfToggle nodisplays}
  1294.     "notransforms" {mfToggle notransforms}
  1295.     "screenchars" {mfToggle screenchars}
  1296.     "screenstrokes" {mfToggle screenstrokes}
  1297.     "clearAllOptions" {clearAllOptionsProc}
  1298.     }    
  1299. }
  1300.  
  1301.  
  1302. proc mfToggle {var} {
  1303.     global $var
  1304.     set $var [expr [set $var] ? 0 : 1]
  1305.     synchroniseModeVar $var
  1306.     shadowMf $var
  1307. }
  1308.  
  1309.  
  1310. proc shadowMf {name} {
  1311.     global gfcorners imagerules nodisplays
  1312.     global notransforms screenchars screenstrokes
  1313.     switch $name {
  1314.         "gfcorners"    {
  1315.             markMenuItem processingOptions gfcorners $gfcorners
  1316.          }
  1317.         "imagerules"    {
  1318.             markMenuItem processingOptions imagerules $imagerules
  1319.          }
  1320.         "nodisplays"    {
  1321.             markMenuItem processingOptions nodisplays $nodisplays
  1322.          }
  1323.         "notransforms"    {
  1324.             markMenuItem processingOptions notransforms $notransforms
  1325.          }
  1326.         "screenchars"    {
  1327.             markMenuItem processingOptions screenchars $screenchars
  1328.          }
  1329.         "screenstrokes"    {
  1330.             markMenuItem processingOptions screenstrokes $screenstrokes
  1331.          }
  1332.     }
  1333. }
  1334.  
  1335. proc clearAllOptionsProc {} {
  1336.     global gfcorners imagerules nodisplays
  1337.     global notransforms screenchars screenstrokes
  1338.     global mag magflag magstep magstepflag Mfbasefile Mfbasefileflag
  1339.         foreach i {"gfcorners" "imagerules" "nodisplays" "notransforms" "screenchars" "screenstrokes"} {
  1340.             set $i 0
  1341.             shadowMf $i
  1342.             }
  1343.         set mag 1
  1344.         set magflag 0
  1345.         set magstep 0
  1346.         set magstepflag 0
  1347.         set Mfbasefileflag 0
  1348.         set Mfbasefile ""
  1349.         markMenuItem processingOptions "baseFile..." $Mfbasefileflag
  1350.         markMenuItem processingOptions "mag..." $magflag
  1351.         markMenuItem processingOptions "magstep..." $magstepflag
  1352. }
  1353.  
  1354. proc dimmOtherfiles {} {
  1355.         enableMenuItem otherFiles "convertTfmToPl" 0
  1356.         enableMenuItem otherFiles "openPropertyList" 0
  1357. }
  1358.  
  1359. proc undimmOtherfiles {} {
  1360.         enableMenuItem otherFiles "convertTfmToPl" 1
  1361.         enableMenuItem otherFiles "openPropertyList" 1
  1362. }
  1363.  
  1364.  
  1365. ######################   Related files procs  #####################################
  1366.  
  1367. proc getMfVersion {} {
  1368.     set sig "CMT3"
  1369.     set vers [objectProperty 'MACS' vers "obj {want:type(file), seld:$sig, form:fcrt, from:'null'()}"]
  1370.     if {[regexp {\“.* (.*)©.*\”\}$} $vers longvers numvers]} {
  1371.     return [list [string trim $longvers "\r\}"] [string trim $numvers "\r\}"]]
  1372.     } else {alertnote "Can't get version info"}
  1373. }
  1374.  
  1375. proc getFSSpec {directory} {
  1376.     global res 
  1377.     set res [AEBuild -r 'MACS' core getd {----} "obj{want:type('cobj'), from:'null'(), form:'name', seld:[curlyq $directory]}"  rtyp fss]
  1378.     if { [regexp {\«(.*)\»} $res blabla fssreco] } {
  1379.     return $fssreco
  1380.     } else {alertnote "Couldn't find FSSpec Record"}
  1381. }
  1382.  
  1383. # This proc looks in the current log file for a line indicating the name of
  1384. # the output file produced by Metafont so that we do not have to calculate
  1385. # the extension (which depends on the printer mode and the magnification)
  1386. proc findgfFile {} {
  1387.     global rootname MfmodeVars outputFolder mfAppSig gffile 
  1388.     global folderpath mfwd mfset
  1389.     switch $MfmodeVars(mfAppSig) {
  1390.         "CMT3" {     
  1391.             if $mfset {
  1392.                 set mfwd $folderpath
  1393.             } else {set mfwd $MfmodeVars(outputFolder)}
  1394.             if {![file exists $mfwd:${rootname}.log]} {
  1395.                 beep 
  1396.                 alertnote "Can't find file ${rootname}.log ; did you process ${rootname}.mf ?"
  1397.                 return}
  1398.                 catch {open "$mfwd:${rootname}.log"} fileId
  1399.             }
  1400.             "OzMF" {
  1401.                 if $mfset {
  1402.                     set mfwd $folderpath
  1403.                 } else {set mfwd [file dirname [win::Current]]}
  1404.                 if {![file exists $mfwd:${rootname}.log]} {
  1405.                     beep 
  1406.                     alertnote "Can't find file ${rootname}.log ; did you process ${rootname}.mf ? Check that the \"delete_log\" flag in OzMetafont configs is set to false."
  1407.                     return}
  1408.                     catch {open "$mfwd:${rootname}.log"} fileId
  1409.                 }
  1410.                 "TeX+"  {
  1411.                     alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1412.                 }
  1413.             }
  1414.             catch {read $fileId} textlog
  1415.             set textlog [split $textlog]
  1416.             catch {lsearch   -regexp  $textlog .*gf} indx
  1417.             if {[expr $indx > 0]} {
  1418.                 set gffile [lindex $textlog $indx]
  1419.             } else {
  1420.                 alertnote "According to ${rootname}.log, no gf output written."
  1421.             }
  1422.         }
  1423.         
  1424. proc findoutputfolder {} {
  1425.     global MfmodeVars outputFolder
  1426.     if {$MfmodeVars(outputFolder) == "" } {
  1427.         catch {get_directory -p "Select the output folder"} rootpath
  1428.         set MfmodeVars(outputFolder) [set rootpath]
  1429.          addArrDef MfmodeVars outputFolder $rootpath
  1430.     }
  1431. }
  1432.  
  1433. proc findrootnameProc {} {
  1434.     global rootname 
  1435.       set rootname [file rootname [file tail [win::Current]]]
  1436.     return
  1437. }
  1438.  
  1439. proc openmodesmfProc {} {
  1440.             global  MfmodeVars pathToModesMfFile
  1441.             if {[file exists $MfmodeVars(pathToModesMfFile) ]} {
  1442.             message "opening $MfmodeVars(pathToModesMfFile)"
  1443.             edit -r $MfmodeVars(pathToModesMfFile) 
  1444.             } else {
  1445.             alertnote "Can't find file modes.mf : where is it ?"
  1446.             catch    {getfile "Find file modes.mf"}  chemin
  1447.             removeArrDef MfmodeVars pathToModesMfFile
  1448.             set pathToModesMfFile $chemin
  1449.             set MfmodeVars(pathToModesMfFile) [set chemin]
  1450.              addArrDef MfmodeVars pathToModesMfFile $chemin
  1451.               edit -r $MfmodeVars(pathToModesMfFile)
  1452.             }
  1453. }
  1454.  
  1455. proc openplainmfProc  {} {
  1456.             global  MfmodeVars pathToPlainMfFile
  1457.             if {[file exists $MfmodeVars(pathToPlainMfFile) ]} {
  1458.             message "opening $MfmodeVars(pathToPlainMfFile)"
  1459.             edit -r $MfmodeVars(pathToPlainMfFile) 
  1460.             } else {
  1461.             alertnote "Can't find file plain.mf : where is it ?"
  1462.             catch    {getfile "Find file plain.mf"}  chemin
  1463.             removeArrDef MfmodeVars pathToPlainMfFile
  1464.             set pathToPlainMfFile $chemin
  1465.             set MfmodeVars(pathToPlainMfFile) [set chemin]
  1466.              addArrDef MfmodeVars pathToPlainMfFile $chemin
  1467.               edit -r $MfmodeVars(pathToPlainMfFile)
  1468.             }
  1469. }
  1470.  
  1471. proc deleteallfilesProc {ext} { 
  1472.     global MfmodeVars outputFolder
  1473.     switch $MfmodeVars(mfAppSig) {
  1474.         "CMT3" {     
  1475.             set currentdir $MfmodeVars(outputFolder)
  1476.         }
  1477.         "OzMF" {
  1478.             set currentdir [file dirname [win::Current]]    
  1479.         }
  1480.         "TeX+"  {
  1481.             alertnote "Support for Direct Tex Pro still to be done. Sorry !"
  1482.             return
  1483.         }
  1484.     }
  1485.     if {![regexp "gf" $ext] && ![regexp "pk" $ext]} {
  1486.         set ext ".$ext"
  1487.     }
  1488.     set filesindir [glob -nocomplain "$currentdir:*$ext"]
  1489.     switch [buttonAlert "OK to remove all \"$ext\" files from $currentdir ?" "yes" "cancel" ] {
  1490.         "yes" {
  1491.             set longueur [llength $filesindir]
  1492.             if {$longueur == 0} {
  1493.                 alertnote "No \"$ext\" file in output folder."
  1494.                 return }
  1495.             foreach Mffile $filesindir {
  1496.                 removeFile $Mffile
  1497.                 message "$longueur file(s) removed"
  1498.             }
  1499.         }
  1500.         "cancel" {return}
  1501.     }
  1502. }
  1503.     
  1504. proc allAuxfilesProc {ext} {
  1505.     global Mffilename cmdline fromfolder MfmodeVars outputFolder folderpath
  1506.     findoutputfolder
  1507.     set mtf ".mf"
  1508.     set i 0
  1509.     set filesindir [glob -nocomplain "$folderpath:*$mtf"]
  1510.     set longueur [llength $filesindir]
  1511.     if {$longueur == 0} { 
  1512.         alertnote "Folder $folderpath is empty"
  1513.         return } 
  1514.     foreach Mffile $filesindir {
  1515.         if {[file exists "[string trimright $Mffile {.mf}].$ext"]} {
  1516.         edit -r "[string trimright $Mffile {.mf}].$ext"
  1517.         } else {set i [expr $i + 1]}
  1518.     }
  1519.     if {$i == $longueur} {
  1520.         alertnote "No \".$ext\" file(s)"
  1521.         } elseif {[expr $i > 0]} {alertnote "$i \".$ext\" file(s) missing."}
  1522. }
  1523.  
  1524. proc convertallProc {applic} {
  1525.     global cmdline fromfolder MfmodeVars outputFolder folderpath
  1526.     global rootname gffile mfset mfwd
  1527.     set i 0
  1528.     set mfset 1
  1529.     set ext(gftopk) "log"
  1530.     set ext(vftopl) "tfm"
  1531.     set filesindir [glob -nocomplain "$folderpath:*.mf"]
  1532.     set longueur [llength $filesindir]
  1533.     if {$longueur == 0} {set mfset 0
  1534.         return } 
  1535.     switch [buttonAlert "Process all the files in $folderpath with $applic ? " "yes" "cancel" ] {
  1536.         "yes" {
  1537.             foreach Mffile $filesindir {
  1538.             set rootname [file rootname [file tail $Mffile]]
  1539.             if {[file exists "$folderpath:$rootname.$ext($applic)"]} {
  1540.                 switch $applic {
  1541.                     "gftopk" {                
  1542.                         findgfFile
  1543.                         if {![file exists "$folderpath:$gffile"]} {
  1544.                             set i [expr $i + 1]
  1545.                             }
  1546.                         dopkProc
  1547.                         }
  1548.                     "vftopl" {                
  1549.                         doplProc
  1550.                         while {![file exists "$mfwd:${rootname}.fpl"]} {}
  1551.                         sendQuitEvent 'CMTk'
  1552.                         set longueur [expr $longueur - 1]
  1553.                         app::launchFore "ALFA"
  1554.                         if [expr $longueur > 0] {
  1555.                             alertnote "Click to proceed : $longueur files left."
  1556.                             }
  1557.                         }
  1558.                     }                
  1559.                 } else {
  1560.                         alertnote "Can't find file $folderpath:$rootname.$ext($applic). Check the Metafont mode."
  1561.                         set i [expr $i + 1]
  1562.                         }
  1563.             }
  1564.         }
  1565.         "cancel" {set i $longueur}
  1566.     }
  1567.         set mfset 0
  1568.         if {$i == [llength $filesindir]} {
  1569.         alertnote "No \"pk\" file(s) computed."
  1570.         } elseif {[expr $i > 0]} {alertnote "$i \"pk\" file(s) missing. Check your \"log\" and your \"gf\" files."}
  1571. }
  1572.  
  1573. proc removefilesProc {menu item} {
  1574.     global MfmodeVars mfAppSig
  1575.     switch $item {    
  1576.         "allLogFiles"  {deleteallfilesProc log}
  1577.         "allGfFiles"  {deleteallfilesProc gf}
  1578.         "allPkFiles"  {deleteallfilesProc pk}
  1579.         "allTfmFiles" {deleteallfilesProc tfm}
  1580.         "allPlFiles" {
  1581.             switch $MfmodeVars(mfAppSig) {
  1582.                 "CMT3" {deleteallfilesProc fpl}
  1583.                 "OzMF" {deleteallfilesProc pl}
  1584.                 "TeX+" {alertnote "Support for Direct Tex Pro still to be done. Sorry !"}
  1585.             }
  1586.         }
  1587.         "allOfThem" {
  1588.             foreach ext {"log" "gf" "pk" "tfm" "fpl" "pl"} {
  1589.                 deleteallfilesProc $ext
  1590.             }
  1591.         }
  1592.     }
  1593. }
  1594.     
  1595. ######################   Insert commands submenus   #####################################
  1596.  
  1597. proc newtemplateProc {} {
  1598.     new -n "newfont.mf"
  1599. #     Ask how many chars in the font
  1600.     beep
  1601.     catch {prompt "How many chars in the new font ?" 128} nbchr
  1602.     if {$nbchr == "cancel"} {
  1603.         return
  1604.     } elseif {![isPositiveInteger $nbchr]} {
  1605.         beep
  1606.         message "invalid input: please enter a positive integer"
  1607.         return
  1608.     }
  1609. #     Preambule instruction
  1610.     set t "\% This file : \n"
  1611.     append t "\% Created : [creationdate]\n"    
  1612.     append t "\% Author : •\n"    
  1613.     append t "\% e-mail : •\n"    
  1614.     append t "\% Comments :•\n%\n%\n%\n\n"    
  1615.     append t "font_size  •pt\#;    \% the \"design size\" of this font\n\n"
  1616.     append t "mode_setup;"
  1617.     append t "\n\n\%\%\%\% Parameters \%\%\%\%\n\n"
  1618.     append t "\n\n\%\%\%\% Pixellisation \%\%\%\%\n\n"
  1619.     append t "define_pixels(•);\n"
  1620.     append t "define_whole_pixels(•);\n"
  1621.     append t "define_whole_vertical_pixels(•);\n"
  1622.     append t "define_blacker_pixels(•);\n"
  1623.     append t "define_good_x_pixels(•);\n"
  1624.     append t "define_good_y_pixels(•);\n"
  1625.     append t "define_corrected_pixels(•);\n"
  1626.     append t "define_horizontal_corrected_pixels(•);\n"
  1627.     append t "\n\n\%\%\%\% Macros and definitions \%\%\%\%\n\n"
  1628.     append t "\n\n\%\%\%\% Drawing instruction for the characters \%\%\%\%\n\n"
  1629.     insertText $t
  1630.     set i 0
  1631.     for {set i 0} {$i < $nbchr} {incr i} {
  1632.             insertText "beginchar([set i],•,•,•);\"•\";\n\n\n\nendchar;\n\n"
  1633.         }
  1634. #     Postambule instruction
  1635.     set t "\n\n\%\%\%\% Ligtables and kerning \%\%\%\%\n\n"
  1636.     append t "ligtable \"•\": \"•\" kern • \#;\n"
  1637.     append t "\n\n\%\%\%\% General Font Parameters \%\%\%\%\n\n"    
  1638.     append t "font_slant:=• ;\n"
  1639.     append t "font_normal_space:=• ;\n"
  1640.     append t "font_normal_stretch:=• ;\n"
  1641.     append t "font_normal_shrink:=•;\n"
  1642.     append t "font_quad:=• ;\n"
  1643.     append t "font_x_height:=• ;\n"
  1644.     append t "font_extra_space:=• ;\n"
  1645.     append t "\nfont_coding_scheme:= \"•\";\n"
  1646.     append t "font_identifier:= \"•\";\n"
  1647.     append t "\n\nbye"
  1648.     insertText $t
  1649. }
  1650.  
  1651. proc creationdate {} {
  1652.     set date [lindex [mtime [now] long] 0]
  1653.     append date " - [lindex [mtime [now] long] 1]"
  1654.     return $date    
  1655. }
  1656.  
  1657. proc variablesProc {menu item} {
  1658.     switch $item {    
  1659.     " boolean" {insertObject "boolean ••;\n••"}
  1660.     " numeric" {insertObject "numeric ••;\n••"}
  1661.     " pair" {insertObject "pair ••;\n••"}
  1662.     " path" {insertObject "path ••;\n••"}
  1663.     " pen" {insertObject "pen ••;\n••"}
  1664.     " picture" {insertObject "picture ••;\n••"}
  1665.     " string" {insertObject "string ••;\n••"}
  1666.     " transform" {insertObject "transform ••;\n••"}
  1667.     }
  1668. }
  1669. proc booleanProc {menu item} {
  1670.     switch $item {    
  1671.     " charexists" {insertObject "charexists ••;\n••"}
  1672.     " cycle" {insertObject "cycle ••;\n••"}
  1673.     " false" {insertObject "false ••;\n••"}
  1674.     " known" {insertObject "known ••;\n••"}
  1675.     " true" {insertObject "true ••;\n••"}
  1676.     " unknown" {insertObject "unknown ••;\n••"}
  1677.     }
  1678. }
  1679. proc functionsProc {menu item} {
  1680.     switch $item {    
  1681.     " angle" {insertObject "angle ••;\n••"}
  1682.     " ceilling" {insertObject "ceilling ••;\n••"}
  1683.     " floor" {insertObject "floor(••)••"}
  1684.     " cosd" {insertObject "cosd(••)••"}
  1685.     " sind" {insertObject "sind(••)"}
  1686.     " mexp" {insertObject "mexp(••)••"}
  1687.     " mlog" {insertObject "mlog(••)••"}
  1688.     " sqrt" {insertObject "sqrt(••)••"}
  1689.     " eps" {insertObject "eps "}
  1690.     " epsilon" {insertObject "epsilon "}
  1691.     " infinity" {insertObject "infinity "}
  1692.     " round" {insertObject "round(••)••"}
  1693.     " hround" {insertObject "hround(••)••"}
  1694.     " vround" {insertObject "vround(••)••"}
  1695.     " solve" {insertObject "solve ••;\n••"}
  1696.     " tolerance" {insertObject "tolerance= ••;\n••"}
  1697.     " normaldeviate" {insertObject "normaldeviate(••)••"}
  1698.     " randomseed" {insertObject "randomseed:= ••;\n••"}
  1699.     " uniformdeviate" {insertObject "uniformdeviate(••)••"}
  1700.     " whatever" {insertObject "whatever "}
  1701.     }
  1702. }
  1703.  
  1704. proc positioningProc {menu item} {
  1705.     switch $item {    
  1706.     " clearxy" {insertObject "clearxy ••;\n••"}
  1707.     " direction" {insertObject "direction •• of ••"}
  1708.     " directionpoint" {insertObject "directionpoint •• of ••"}
  1709.     " directiontime" {insertObject "directiontime •• of ••;\n••"}
  1710.     " penoffset" {insertObject "penoffset •• of ••"}
  1711.     " point…of" {insertObject "point •• of ••"}
  1712.     " precontrol…of" {insertObject "precontrol •• of ••"}
  1713.     " postcontrol…of" {insertObject "postcontrol •• of ••"}
  1714.     " intersectionpoint" {insertObject " •• intersectionpoint ••"}
  1715.     " intersectiontimes" {insertObject "•• intersectiontimes ••"}
  1716.     " good.bot" {insertObject "good.bot "}
  1717.     " good.lft" {insertObject "good.lft "}
  1718.     " good.rt" {insertObject "good.rt "}
  1719.     " good.top" {insertObject "good.top "}
  1720.     " good.x" {insertObject "good.x "}
  1721.     " good.y" {insertObject "good.y "}
  1722.     " xpart" {insertObject "xpart(••)••"}
  1723.     " xxpart" {insertObject "xxpart(••)••"}
  1724.     " xypart" {insertObject "xypart(••)••"}
  1725.     " ypart" {insertObject "ypart(••)••"}
  1726.     " yxpart" {insertObject "yxpar(••)••"}
  1727.     " yypart" {insertObject "yypart(••)••"}
  1728.     }
  1729. }
  1730. proc pathsProc {menu item} {
  1731.     switch $item {    
  1732.     " flex" {mkflexProc}
  1733.     " fullcircle" {insertObject "fullcircle "}
  1734.     " halfcircle" {insertObject "halfcircle "}
  1735.     " quartercircle" {insertObject "quartercircle "}
  1736.     " superellipse" {insertObject "superellipse(••,••,••,••,••);\n••"}
  1737.     " unitsquare" {insertObject "unitsquare "}
  1738.     " makepath" {insertObject "makepath ••;\n••"}
  1739.     " interpath" {insertObject "interpath(••,••,••);\n••"}
  1740.     " subpath" {insertObject "subpath(••,••) of ••"}
  1741.     " tensepath" {insertObject "tensepath "}
  1742.     " counterclockwise" {insertObject "counterclockwise "}
  1743.     " reverse" {insertObject "reverse "}
  1744.     " turningnumber" {insertObject "turningnumber "}
  1745.     }
  1746. }
  1747. proc pensProc {menu item} {
  1748.     switch $item {    
  1749.     " clear_pen_memory" {insertObject "clear_pen_memory;"}
  1750.     " clearpen" {insertObject "clearpen;"}
  1751.     " currentpen" {insertObject "currentpen "}
  1752.     " makepen" {insertObject "makepen "}
  1753.     " nullpen" {insertObject "nullpen;"}
  1754.     " savepen" {insertObject ":=savepen;"}
  1755.     " pencircle" {insertObject "pencircle "}
  1756.     " pencircle..." {insertObject "pencircle •• xscaled •• yscaled ••;\n••"}
  1757.     " pensquare" {insertObject "pensquare "}
  1758.     " pensquare..." {insertObject "pensquare •• xscaled •• yscaled ••;\n••"}
  1759.     " penrazor" {insertObject "penrazor;"}
  1760.     " penspeck" {insertObject "penspeck;"}
  1761.     " pen_bot" {insertObject "pen_bot"}
  1762.     " pen_lft" {insertObject "pen_lft"}
  1763.     " pen_rt" {insertObject "pen_rt"}
  1764.     " pen_top" {insertObject "pen_top"}
  1765.     " pickup" {insertObject "pickup "}
  1766.     }
  1767. }
  1768. proc picturesProc {menu item} {
  1769.     switch $item {    
  1770.     " blankpicture" {insertObject "blankpicture"}
  1771.     " clearit" {insertObject "clearit ••;\n••"}
  1772.     " currentpicture" {insertObject "currentpicture"}
  1773.     " nullpicture" {insertObject "nullpicture"}
  1774.     " totalweight" {insertObject "totalweight "}
  1775.     " unitpixel" {insertObject "unitpixel"}
  1776.     }
  1777. }
  1778. proc stringsProc {menu item} {
  1779.     switch $item {    
  1780.     " ditto" {insertObject "ditto"}
  1781.     " jobname" {insertObject "jobname"}
  1782.     " readstring" {insertObject ":=readstring;"}
  1783.     " substring" {insertObject "substring(••,••) of ••"}
  1784.     }
  1785. }
  1786. proc transformationsProc {menu item} {
  1787.     switch $item {    
  1788.     " currenttransform" {insertObject "currenttransform "}
  1789.     " identity" {insertObject "identity "}
  1790.     " inverse" {insertObject "inverse "}
  1791.     " reflectedabout" {insertObject "reflectedabout(••,••) ••"}
  1792.     " rotated" {insertObject "rotated "}
  1793.     " rotatedaround" {insertObject "rotatedaround(••,••) ••"}
  1794.     " scaled" {insertObject "scaled "}
  1795.     " shifted" {insertObject "shifted "}
  1796.     " slanted" {insertObject "slanted "}
  1797.     " transformed" {insertObject "transformed "}
  1798.     " xscaled" {insertObject "xscaled "}
  1799.     " yscaled" {insertObject "yscaled "}
  1800.     " zscaled" {insertObject "zscaled "}
  1801.     }
  1802. }
  1803. proc definitionsProc {menu item} {
  1804.     switch $item {    
  1805.     " def…enddef" {insertObject "def ••=\n••\nenddef;\n••"}
  1806.     " suffix" {insertObject "(suffix ••)••"}
  1807.     " expr" {insertObject "(expr ••)••"}
  1808.     " text" {insertObject "(text ••)••"}
  1809.     " primarydef…enddef" {insertObject "primarydef ••=\n••\nenddef;\n••"}
  1810.     " secondarydef…enddef" {insertObject "secondarydef ••=\n••\nenddef;\n••"}
  1811.     " tertiarydef…enddef" {insertObject "tertiarydef ••=\n••\nenddef;\n••"}
  1812.     " vardef…enddef" {insertObject "vardef ••=\n••\nenddef;\n••"}
  1813.     " begingroup…endgroup" {insertObject "begingroup ••\nendgroup;\n••"}
  1814.     }
  1815. }
  1816. proc conditionsProc {menu item} {
  1817.     switch $item {    
  1818.     " for…endfor" {insertObject "for •• : •• endfor;\n••"}
  1819.     " forever…endfor" {insertObject "forever •• endfor;\n••"}
  1820.     " forsuffixes…endfor" {insertObject "forsuffixes •• : •• endfor;\n••"}
  1821.     " if…fi" {insertObject "if •• : •• fi\n••"}
  1822.     " if…elseif…else…fi" {insertObject "if •• elseif •• else •• fi\n••"}
  1823.     " downto" {insertObject "downto "}
  1824.     " upto" {insertObject "upto "}
  1825.     " step…until" {insertObject "step •• until •• : ••"}
  1826.     " exitif" {insertObject "exitif ••;"}
  1827.     " exitunless" {insertObject "exitunless ••;"}
  1828.     }
  1829. }
  1830. proc drawingProc {menu item} {
  1831.     switch $item {    
  1832.     " addto…also" {insertObject "addto •• also ••;\n••"}
  1833.     " addto…contour" {insertObject "addto •• contour •• ;\n••"}
  1834.     " addto…contour…withpen" {insertObject "addto •• contour •• withpen ••;\n••"}
  1835.     " addto…contour…withweight" {insertObject "addto •• contour •• withweight ••;\n••"}
  1836.     " addto…doublepath…withpen" {insertObject "addto •• doublepath •• withpen ••;\n••"}
  1837.     " addto…doublepath…withweight" {insertObject "addto •• doublepath •• withweight ••;\n••"}
  1838.     " cull…dropping" {insertObject "cull •• dropping (••,••);\n••"}
  1839.     " cull…dropping…withweight" {insertObject "cull •• dropping (••,••) withweight ••;\n••"}
  1840.     " cull…keeping" {insertObject "cull •• keeping (••,••);\n••"}
  1841.     " cull…keeping…withweight" {insertObject "cull •• keeping (••,••) withweight ••;\n••"}
  1842.     " cullit" {insertObject "cullit ••;\n••"}
  1843.     " cutdraw" {insertObject "cutdraw "}
  1844.     " cutoff" {insertObject "cutoff(••,••);\n••"}
  1845.     " draw" {insertObject "draw "}
  1846.     " drawdot" {insertObject "drawdot ••;\n••"}
  1847.     " erase" {insertObject "erase ••;\n••"}
  1848.     " fill" {insertObject "fill ••;\n••"}
  1849.     " filldraw" {insertObject "filldraw ••;\n••"}
  1850.     " penpos" {insertObject "penpos••(••,••);\n••"}
  1851.     " penstroke" {insertObject "penstroke ••;\n••"}
  1852.     " undraw" {insertObject "undraw ••;\n••"}
  1853.     " undrawdot" {insertObject "undrawdot ••;\n••"}
  1854.     " unfill" {insertObject "unfill ••;\n••"}
  1855.     " unfilldraw" {insertObject "unfilldraw ••;\n••"}
  1856.     }
  1857. }
  1858. proc charactersProc {menu item} {
  1859.     switch $item {    
  1860.     " beginchar…endchar" {insertObject "beginchar(\"••\",••,••,••);\"••\";\n••\nendchar;\n••"}
  1861.     " extra_beginchar" {insertObject "extra_beginchar:=\" •• \";\n••"}
  1862.     " extra_endchar" {insertObject "extra_endchar:=\" •• \";\n••"}
  1863.     }
  1864. }
  1865. proc unitsProc {menu item} {
  1866.     switch $item {    
  1867.     " blacker" {insertObject "blacker=••;\n••"}
  1868.     " fillin" {insertObject "fillin=••;\n••"}
  1869.     " o_correction" {insertObject "o_correction= ••;\n••"}
  1870.     " fix_units" {insertObject "def fix_units= ••;\nenddef\n••"}
  1871.     " mode_setup" {insertObject "mode_setup;\n"}
  1872.     " pixels_per_inchs" {insertObject "pixels_per_inchs=••;\n••"}
  1873.     }
  1874. }
  1875. proc pixellisationProc {menu item} {
  1876.     switch $item {    
  1877.     " define_pixels" {insertObject "define_pixels(••);\n••"}
  1878.     " define_blacker_pixels" {insertObject "define_blacker_pixels(••);\n••"}
  1879.     " define_good_x_pixels" {insertObject "define_good_x_pixels(••);\n••"}
  1880.     " define_good_y_pixels" {insertObject "define_good_y_pixels(••);\n••"}
  1881.     " define_corrected_pixels" {insertObject "define_corrected_pixels(••);\n••"}
  1882.     " define_horizontal_corrected_pixels" {insertObject "define_horizontal_corrected_pixels(••);\n••"}
  1883.     " define_whole_pixels" {insertObject "define_whole_pixels(••);\n••"}
  1884.     " define_whole_blacker_pixels" {insertObject "define_whole_blacker_pixels(••);\n••"}
  1885.     " define_whole_vertical_pixels" {insertObject "define_whole_vertical_pixels(••);\n••"}
  1886.     " define_whole_vertical_blacker_pixels" {insertObject "define_whole_vertical_blacker_pixels(••);\n••"}
  1887.     }
  1888. }
  1889. proc fontdefinitionsProc {menu item} {
  1890.     switch $item {    
  1891.     " charlist" {insertObject "charlist ••: •• : •• : •• : ••"}
  1892.     " extensible" {insertObject "extensible ••: ••, ••, ••, ••"}
  1893.     " font_coding_scheme" {insertObject "font_coding_scheme:= \"••\";\n••"}
  1894.     " font_extra_space" {insertObject "font_extra_space:= ••;\n••"}
  1895.     " font_identifier" {insertObject "font_identifier:= \"••\";\n••"}
  1896.     " font_normal_shrink" {insertObject "font_normal_shrink:= ••;\n••"}
  1897.     " font_normal_space" {insertObject "font_normal_space:= ••;\n••"}
  1898.     " font_normal_stretch" {insertObject "font_normal_stretch:= ••;\n••"}
  1899.     " font_quad" {insertObject "font_quad:= ••;\n••"}
  1900.     " font_size" {insertObject "font_size:= ••;\n••"}
  1901.     " font_slant" {insertObject "font_slant:= ••;\n••"}
  1902.     " font_x_height" {insertObject "font_x_height:= ••;\n••"}
  1903.     " fontdimen" {insertObject "fontdimen ••: ••, ••, ••, ••\n••"}
  1904.     " headerbytes" {insertObject "headerbytes ••: ••, ••, ••, ••"}
  1905.     " ligtable" {insertObject "ligtable \"••\" : \"••\" =: oct\"••\";\n••"}
  1906.     " kern" {insertObject "kern ••\#••"}
  1907.     }
  1908. }
  1909. proc displayingProc {menu item} {
  1910.     switch $item {    
  1911.     " currentwindow" {insertObject "currentwindow:= ••;\n••"}
  1912.     " display…inwindow" {insertObject "display •• inwindow ••;\n••"}
  1913.     " openwindow…from…to…at" {insertObject "openwindow •• from (••,••) to (••,••) at (••,••);\n••"}
  1914.     " screen_cols" {insertObject "screen_cols:= ••;\n••"}
  1915.     " screen_rows" {insertObject "screen_rows:= ••;\n••"}
  1916.     " screenrule" {insertObject "screenrule(••,••);\n••"}
  1917.     }
  1918. }
  1919. proc outputProc {menu item} {
  1920.     switch $item {    
  1921.     " openit" {insertObject "openit;\n"}
  1922.     " shipit" {insertObject "shipit;\n"}
  1923.     " showit" {insertObject "showit;\n"}
  1924.     " labels" {insertObject "labels(••);\n••"}
  1925.     " labels…range…thru" {insertObject "labels(range •• thru ••);\n••"}
  1926.     " penlabels" {insertObject "penlabels(••);\n••"}
  1927.     " makelabel" {insertObject "makelabel(\"••\",••);\n••"}
  1928.     " makegrid..." {mkgridProc}
  1929.     " proofoffset" {insertObject "proofoffset(••,••);\n••"}
  1930.     " proofrule" {insertObject "proofrule(••,••);\n••"}
  1931.     " proofrulethickness" {insertObject "proofrulethickness:=••;\n••"}
  1932.     " grayfont" {insertObject "grayfont \"••\";\n••"}
  1933.     " labelfont" {insertObject "labelfont \"••\";\n••"}
  1934.     " slantfont" {insertObject "slantfont \"••\";\n••"}
  1935.     " titlefont" {insertObject "titlefont \"••\";\n••"}
  1936.     }
  1937. }
  1938. proc debuggingProc {menu item} {
  1939.     switch $item {    
  1940.     " errhelp" {insertObject "errhelp "}
  1941.     " errmessage" {insertObject "errmessage \"••\";\n••"}
  1942.     " message" {insertObject "message \"••\";\n••"}
  1943.     " stop" {insertObject "stop;\n"}
  1944.     " show" {insertObject "show ••;\n••"}
  1945.     " showdependencies" {insertObject "showdependencies;\n"}
  1946.     " showstats" {insertObject "showstats;\n"}
  1947.     " showtoken" {insertObject "showtoken ••;\n••"}
  1948.     " showvariable" {insertObject "showvariable ••;\n••"}
  1949.     " loggingall" {insertObject "loggingall:= ••\n••"}
  1950.     " tracingall" {insertObject "tracingall:= ••\n••"}
  1951.     " tracingnone" {insertObject "tracingnone:= ••\n••"}
  1952.     " batchmode" {insertObject "batchmode;\n••"}
  1953.     " errorstopmode" {insertObject "errorstopmode;\n••"}
  1954.     " nonstopmode" {insertObject "nonstopmode;\n••"}
  1955.     " scrollmode" {insertObject "scrollmode;\n••"}
  1956.     }
  1957. }
  1958. proc miscProc {menu item} {
  1959.     switch $item {    
  1960.     " capsule_def" {insertObject "capsule_def ••;\n••"}
  1961.     " expandafter" {insertObject "expandafter "}
  1962.     " gobble" {insertObject "gobble "}
  1963.     " gobbled" {insertObject "gobbled "}
  1964.     " interact" {insertObject "interact;\n••"}
  1965.     " numtok" {insertObject "numtok "}
  1966.     " scantokens" {insertObject "scantokens "}
  1967.     " special" {insertObject "special \" ••\";\n••"}
  1968.     " numspecial" {insertObject "numspecial ••;\n••"}
  1969.     }
  1970. }
  1971. proc varintProc {menu item} {
  1972.     switch $item {    
  1973.     " autorounding" {insertObject "autorounding:= ••;\n••"}
  1974.     " designsize" {insertObject "designsize:= ••;\n••"}
  1975.     " fontmaking" {insertObject "fontmaking:= ••;\n••"}
  1976.     " granularity" {insertObject "granularity:= ••;\n••"}
  1977.     " pausing" {insertObject "pausing:= ••;\n••"}
  1978.     " proofing" {insertObject "proofing:= ••;\n••"}
  1979.     " showstopping" {insertObject "showstopping:= ••;\n••"}
  1980.     " smoothing" {insertObject "smoothing:= ••;\n••"}
  1981.     " charcode" {insertObject "charcode:= ••;\n••"}
  1982.     " chardp" {insertObject "chardp:= ••;\n••"}
  1983.     " chardx" {insertObject "chardx:= ••;\n••"}
  1984.     " chardy" {insertObject "chardy:= ••;\n••"}
  1985.     " charext" {insertObject "charext:= ••;\n••"}
  1986.     " charht" {insertObject "charht:= ••;\n••"}
  1987.     " charic" {insertObject "charic:= ••;\n••"}
  1988.     " charwd" {insertObject "charwd:= ••;\n••"}
  1989.     " hppp" {insertObject "hppp:= ••;\n••"}
  1990.     " vppp" {insertObject "vppp:= ••;\n••"}
  1991.     " xoffset" {insertObject "xoffset:= ••;\n••"}
  1992.     " yoffset" {insertObject "yoffset:= ••;\n••"}
  1993.     " day" {insertObject "day;"}
  1994.     " month" {insertObject "month;"}
  1995.     " year" {insertObject "year;"}
  1996.     " time" {insertObject "time;"}
  1997.     " tracingcapsules" {insertObject "tracingcapsules:= ••;\n••"}
  1998.     " tracingchoices" {insertObject "tracingchoices:= ••;\n••"}
  1999.     " tracingcommands" {insertObject "tracingcommands:= ••;\n••"}
  2000.     " tracingedges" {insertObject "tracingedges:= ••;\n••"}
  2001.     " tracingequations" {insertObject "tracingequations:= ••;\n••"}
  2002.     " tracingmacros" {insertObject "tracingmacros:= ••;\n••"}
  2003.     " tracingonline" {insertObject "tracingonline:= ••;\n••"}
  2004.     " tracingoutput" {insertObject "tracingoutput:= ••;\n••"}
  2005.     " tracingpens" {insertObject "tracingpens:= ••;\n••"}
  2006.     " tracingrestores" {insertObject "tracingrestores:= ••;\n••"}
  2007.     " tracingspecs" {insertObject "tracingspecs:= ••;\n••"}
  2008.     " tracingstats" {insertObject "tracingstats:= ••;\n••"}
  2009.     " tracingtitles" {insertObject "tracingtitles:= ••;\n••"}
  2010.     " turningcheck" {insertObject "turningcheck:= ••;\n••"}
  2011.     " warningcheck" {insertObject "warningcheck:= ••;\n••"}
  2012.     }
  2013. }
  2014.  
  2015. # In this proc, choose the number of horizontal and vertical lines
  2016. # in a grid
  2017. proc mkgridProc {} {
  2018.     set macroName "makegrid"
  2019.     beep
  2020.     catch {prompt "$macroName:  how many x-coordinates ?" 3} numbx
  2021.     if {$numbx == "cancel"} {
  2022.         return
  2023.     } elseif {![isPositiveInteger $numbx]} {
  2024.         beep
  2025.         message "invalid input: please enter a positive integer"
  2026.         return
  2027.     }
  2028.     catch {prompt "$macroName:  how many y-coordinates ?" 3} numby
  2029.     if {$numby == "cancel"} {
  2030.         return
  2031.     } elseif {![isPositiveInteger $numby]} {
  2032.         beep
  2033.         message "invalid input: please enter a positive integer"
  2034.         return
  2035.     }
  2036.     if {$numbx && $numby} {
  2037.         set body "makegrid(••"
  2038.         for {set i 1} {$i < $numbx} {incr i} {
  2039.             append body ",••"
  2040.         }
  2041.         append body ")(••"
  2042.         for {set i 1} {$i < $numby} {incr i} {
  2043.             append body ",••"
  2044.         }
  2045.         append body ");\n••"
  2046.     } else {
  2047.         set body "••\r"
  2048.     }
  2049.     insertObject $body
  2050. }
  2051.  
  2052. # In this proc, choose the number of points on a flex path
  2053. proc mkflexProc {} {
  2054.     set macroName "flex"
  2055.     beep
  2056.     catch {prompt "$macroName:  how many points on the flex-path ?" 3} numbp
  2057.     if {$numbp == "cancel"} {
  2058.         return
  2059.     } elseif {![isPositiveInteger $numbp]} {
  2060.         beep
  2061.         message "invalid input: please enter a positive integer"
  2062.         return
  2063.     }
  2064.     if {$numbp} {
  2065.         set body "flex(••"
  2066.         for {set i 1} {$i < $numbp} {incr i} {
  2067.             append body ",••"
  2068.         }
  2069.         append body ") ••"
  2070.     } else {
  2071.         set body "••\r"
  2072.     }
  2073.     insertObject $body
  2074. }
  2075.  
  2076.  
  2077. #########   Syntax Colorizing  ###########
  2078.  
  2079. set    mfKeyWords    { 
  2080. abs addto also and angle at autorounding batchmode beginchar begingroup blacker 
  2081. blankpicture boolean bot bye byte capsule_def ceilling change_width char character 
  2082. charcode chardp chardx chardy charexists charext charht charic charlist 
  2083. charwd checksum clear_pen_memory clearit clearpen clearxy codingscheme  comment contour 
  2084. cosd counterclockwise cull cullit currentpen currentpicture currenttransform 
  2085. currentwindow cutdraw cutoff cycle day decimal decr def define_blacker_pixels 
  2086. define_good_x_pixels define_good_y_pixels define_pixels define_whole_pixels designsize 
  2087. direction directionpoint directiontime display displaying ditto dotprod doublepath downto 
  2088. draw drawdot dropping else elseif end endchar enddef endfor endgroup eps epsilon 
  2089. erase errhelp errmessage errorstopmode exitif exitunless extensible extra_beginchar extra_endchar 
  2090. extraspace face false family fi fill filldraw fillin fix_units flex floor font_coding_scheme font_extra_space 
  2091. font_identifier font_normal_shrink font_normal_space font_normal_stretch font_quad 
  2092. font_size font_slant font_x_height fontdimen fontmaking forever forsuffixes from 
  2093. fullcircle gfcorners gobble gobbled good.bot good.lft good.rt good.top good.x good.y 
  2094. granularity grayfont halfcircle headerbytes hex hide hppp hround identity if imagerules 
  2095. incr infinity input interact interim interpath intersectionpoint intersectiontimes 
  2096. inverse inwindow italcorr jobname join_radius keeping kern known label labelfont labels length 
  2097. let lft ligtable loggingall makegrid makelabel makepath makepen max message mexp min 
  2098. mlog mode_setup month nodisplays nonstopmode normaldeviate not notransforms 
  2099. nullpen nullpicture numeric numspecial numtok o_correction oct 
  2100. odd openit openwindow or pair path pausing pen pen_bot pen_lft 
  2101. pen_rt pen_top pencircle penlabels penoffset penpos penrazor penspeck pensquare 
  2102. penstroke pickup picture pixels_per_inchs point postcontrol precontrol primarydef 
  2103. proofing proofoffset proofrule proofrulethickness quad quartercircle range readstring reflectedabout 
  2104. reverse rotated rotatedaround round rt save savepen scaled scantokens screen_cols 
  2105. screen_rows screenchars screenrule screenstrokes scrollmode secondarydef shifted shipit show 
  2106. showdependencies showit showstats showstopping showtoken showvariable shrink sind slant slanted 
  2107. slantfont smoothing solve space special sqrt step stop str stretch string subpath substring superellipse 
  2108. tensepath tertiarydef thru time titlefont to tolerance top totalweight tracingall tracingcapsules 
  2109. tracingchoices tracingcommands tracingedges tracingequations tracingmacros tracingnone 
  2110. tracingonline tracingoutput tracingpens tracingrestores tracingspecs tracingstats 
  2111. tracingtitles tracingtitles transform transformed true turningcheck turningnumber 
  2112. undraw undrawdot unfill unfilldraw uniformdeviate unitpixel unitsquare unknown until 
  2113. upto vardef vppp vround warningcheck whatever withpen withweight xheight xoffset xpart xscaled 
  2114. xxpart xypart year yoffset yoffset ypart yscaled yxpart yypart zscaled 
  2115. }
  2116.  
  2117.  
  2118. regModeKeywords  -e {%} -c $MfmodeVars(commentColor) \
  2119.   -k $MfmodeVars(keywordColor)  -s $MfmodeVars(stringColor) Mf $mfKeyWords
  2120. unset mfKeyWords
  2121.  
  2122. ############   Completions  ################
  2123.  
  2124. set completions(Mf) {completion::electric}
  2125.  
  2126. set Mfelectrics(for)  " •• : •• endfor;\n••"
  2127. set Mfelectrics(beginchar)   "(\"••\",••,••,••);\"••\";\n••\nendchar;\n••"
  2128. set Mfelectrics(def)   " ••=\n••\nenddef;\n••"
  2129. set Mfelectrics(primarydef)   " ••=\n••\nenddef;\n••"
  2130. set Mfelectrics(secondarydef)   " ••=\n••\nenddef;\n••"
  2131. set Mfelectrics(tertiarydef)   " ••=\n••\nenddef;\n••"
  2132. set Mfelectrics(vardef)   " ••=\n••\nenddef;\n••"
  2133. set Mfelectrics(begingroup)   " ••\nendgroup;\n••"
  2134. set Mfelectrics(forever)   " •• endfor;\n••"
  2135. set Mfelectrics(forsuffixes)   " •• : •• endfor;\n••"
  2136. set Mfelectrics(if)   " •• : •• fi\n••"
  2137.  
  2138.  
  2139. ############   Key Bindings  ################
  2140.  
  2141. # Are there bindings necessary in this mode ?
  2142.  
  2143. ##########    File Marking  ############
  2144. # All the "def" and "vardef" definitions in a mf source file will be marked in the "M" 
  2145. # pop-up menu (top right of the current window). All the beginchar/endchar groups will 
  2146. # be marked too (even if you changed the name of this environment in the mode specific prefs :
  2147. # if you chose to call them "myfontchar" then all the "myfontchar" instructions will be marked)
  2148.  
  2149. proc Mf::MarkFile {} {
  2150.     global MfmodeVars
  2151.     set bgnch $MfmodeVars(userBeginchar)
  2152.     set end [maxPos]
  2153.     set pos 0
  2154.      while {![catch {search -f 1 -r 1 -m 0 -i 0 {^'$bgnch'[ _\w\d\(\"]*|^def[ _\w]*|^vardef[ _\w]*} $pos} res]} {
  2155.         set start [lindex $res 0]
  2156.         set end [lindex $res 1]
  2157.         set txt [getText [expr $start - 1] $end]
  2158.         set pos [nextLineStart $start]
  2159.         set inds($txt) [lineStart [expr $start - 1]]
  2160.     }
  2161.  
  2162.     if {[info exists inds]} {
  2163.          foreach f [lsort [array names inds]] {
  2164.             set next [nextLineStart $inds($f)]
  2165.             setNamedMark $f $inds($f) $next $next
  2166.         }
  2167.     }
  2168.     set end [maxPos]
  2169.     set pos 0
  2170.      while {![catch {search -f 1 -r 0 -m 0 -i 0 $bgnch $pos} res]} {
  2171.         set start [lindex $res 0]
  2172.         set end [nextLineStart $start]
  2173.         set txt [getText [expr $start - 1] $end]
  2174.         set pos [nextLineStart $start]
  2175.         set inds($txt) [lineStart [expr $start - 1]]
  2176.     }
  2177.  
  2178.     if {[info exists inds]} {
  2179.          foreach f [lsort [array names inds]] {
  2180.             set next [nextLineStart $inds($f)]
  2181.             setNamedMark $f $inds($f) $next $next
  2182.         }
  2183.     }
  2184. }
  2185.  
  2186.